#ifndef FlAG_H
#define FlAG_H

namespace Y{

typedef unsigned long long Sull;

template <class C>
struct Flag_t{
	Flag_t (){ value = 0; }
	
	Flag_t (C val):
		value(val)
	{}
	
	Flag_t ( const Flag_t& f ):
		value(f.value)
	{}
	Flag_t& operator= ( const Flag_t& f ){ value = f.value;return *this; }
	
	C value;
	
	void toggleFlag (C par)			{ value ^= par; }
	void addFlag (C par)			{ value |= par; }
	void add (C par)				{ value |= par; }
	void removeFlag (C par)			{ value &= ~par; }
	void remove (C par)				{ value &= ~par; }
	void setFlagTo (C par, bool b)	{ if (b){addFlag(par);}else{removeFlag(par);} }
	bool flagSet (C par) const		{ return ((value & par) == par); }
		bool includes (C par) const	{ return ((value & par) == par); }
	void operator |= (C par)		{ value |= par;}
	
	void operator-= (C s)			{ removeFlag(s); }
	void operator+= (C s)			{ addFlag(s); }
	void operator= (C s)			{ set(s); }
	bool operator== (C s) const		{ return (value == s); }
	bool operator== (const Flag_t& r) const { return (r.value == value); }
	bool operator!= (C s) const		{ return (value != s); }
	
	void set (C val)				{ value = val; }
	C  get (void) const				{ return value; }
};


typedef Flag_t<unsigned long long> Flag;
typedef Flag_t<unsigned char> Flag_8;
typedef Flag_t<unsigned short> Flag_16;
typedef Flag_t<unsigned int> Flag_32;
typedef Flag_t<unsigned long long> Flag_64;

typedef Flag_t<unsigned char> Flag_char;
typedef Flag_t<unsigned short> Flag_short;
typedef Flag_t<unsigned int> Flag_int;
typedef Flag_t<unsigned long long> Flag_long_long;

}

#endif